home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1998-04-30 | 21.4 KB | 758 lines | [ TEXT/MPS ]
/* File: OTDNRSample.cp Contains: Sample showing use of the Open Transport MacTCP Domain Name Resolver Copyright: © 1994-1997 by Apple Computer, Inc., all rights reserved. */ #include <Types.h> #include <Events.h> #include <SegLoad.h> #include <String.h> #include <strings.h> #include <Quickdraw.h> #include <Stdio.h> #include <StdLib.h> #include <Menus.h> #include <Devices.h> #include <OpenTptInternet.h> const UInt16 kNumMX = 10; const size_t kQueryBufSize = 4096; const size_t kArgBufSize = 8; // Support eight argvs Boolean gCallCompleted = false; InetSvcRef gSvc = NULL; InetDomainName gDomainName; InetHostInfo gMyHInfo; InetSysInfo gMySysInfo; InetMailExchange gMyMX[kNumMX]; UInt16 gNumMX; UInt8 gQueryBuf[kQueryBufSize]; void* gArgBuf[kArgBufSize]; OTResult gTestResult = kOTNoError; const int kStrToAddrTest = 1; const int kAddrToNameTest = 2; const int kSysInfoTest = 3; const int kMXTest = 4; const int kQueryTest = 5; enum { kAType = 1, kNSType = 2, kMDType = 3, kMFType = 4, kCNameType = 5, kSOAType = 6, kMBType = 7, kMGType = 8, kMRType = 9, kNullType = 10, kWKSType = 11, kPtrType = 12, kHInfoType = 13, kMInfoType = 14, kMXType = 15, kTxtType = 16, kRPType = 17, kAFDSBType = 18, kX25Type = 19, kISDNType = 20, kRTType = 21, kAXFRTYpe = 252, kMailBType = 253, kMailAType = 254, kWIldCardType = 255 }; struct WKSEntry { UInt8 WKSAddr[4]; UInt8 WKSProto; char WKSBitMask[4]; }; typedef struct WKSEntry WKSEntry; const char* TypeOfQuery[256] = {"Unknown", "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG", "MR", "Null", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT", "RP", "AFDSB", "X25", "ISDN", "RTT", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "AXFR", "MAILB", "MAILA", "WILDCARD"}; const char* TypeOfClass[256] = {"Unknown", "IN", "CS", "CH", "HS", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "WILDCARD"}; const char* TypeOfRR[5] = {"Unknown", "Question", "Answer", "Authority", "Additional"}; const char* TypeOfProtocol[18] = {"Reserved", "ICMP", "IGMP", "GGP", "IP", "ST", "TCP", "UCL", "EGP", "IGP", "BBN-RC-MON", "NVP-II", "PUP", "ARGUS", "EMCON", "XNET", "CHAOS", "UDP"}; // Only Need This Many For Test void Inits() { /* * Do standard inits */ InitGraf(&qd.thePort); if ( InitOpenTransport() != kOTNoError ) { fprintf(stderr, "dnrtest: Could not initialize ASLM, exiting\n"); exit(1); } } void CleanMyHInfo() { UInt8* start = (UInt8*)&gMyHInfo; size_t idx; for (idx = 0; idx < sizeof(InetHostInfo); idx++) start[idx] = 0; } void CleanMyDomainName() { UInt8* start = (UInt8*)gDomainName; size_t idx; for (idx = 0; idx < sizeof(gDomainName); idx++) start[idx] = 0; } void CleanMySysInfo() { UInt8* start = (UInt8*)&gMySysInfo; size_t idx; for (idx = 0; idx < sizeof(InetHostInfo); idx++) start[idx] = 0; } void CleanMyMX() { UInt8* start = (UInt8*)gMyMX; size_t idx; for (idx = 0; idx < sizeof(InetMailExchange) * kNumMX; idx++) start[idx] = 0; } void CleanMyQueryBuf() { UInt8* start = (UInt8*)gQueryBuf; size_t idx; for (idx = 0; idx < kQueryBufSize; idx++) start[idx] = 0; } void DoStrToAddr(char* name) { size_t idx; union { InetHost addr; UInt8 bytes[4]; } tmpaddr; CleanMyHInfo(); OSStatus err = gSvc->StringToAddress(name, &gMyHInfo); if ( err != kOTNoError ) gTestResult = err; else { while ( !gCallCompleted ) ; } switch ( gTestResult ) { case kOTNoError: fprintf(stderr, "Canonical Name = %s \n", gMyHInfo.name); for ( idx = 0; idx < kMaxHostAddrs; idx++) { if ( gMyHInfo.addrs[idx] == NULL ) break; tmpaddr.addr = gMyHInfo.addrs[idx]; fprintf(stderr, "Address %d = %d.%d.%d.%d \n", idx, tmpaddr.bytes[0], tmpaddr.bytes[1], tmpaddr.bytes[2], tmpaddr.bytes[3]); } break; case kENOMEMErr: fprintf(stderr, "Memory Depletion!\n"); break; case kEINVALErr: fprintf(stderr, "Host Address Wrong Size! Shouldn't Happen In This Test!\n"); break; case kOTNoDataErr: fprintf(stderr, "No Data Available! Either Timeout,or Name Exists But Requested Info Doesn't!\n"); break; case kOTBadNameErr: fprintf(stderr, "Bad Name! Either Name Does Not Exist in Domains Examined, or Bad Syntax!\n"); break; default: fprintf(stderr, "Unknown Error!\n"); break; } gCallCompleted = false; gTestResult = kOTNoError; } void DoAddrToName(InetHost addr) { CleanMyDomainName(); OSStatus err = gSvc->AddressToName(addr, gDomainName); if ( err != kOTNoError ) gTestResult = err; else { while ( !gCallCompleted ) ; } switch ( gTestResult ) { case kOTNoError: fprintf(stderr, "Canonical Name = %s \n", gDomainName); break; case kENOMEMErr: fprintf(stderr, "Memory Depletion!\n"); break; case kEINVALErr: fprintf(stderr, "Host Address Wrong Size! How'd That Happen?\n"); break; case kOTNoDataErr: fprintf(stderr, "No Data Available! Either Timeout,or Name Exists But Requested Info Doesn't!\n"); break; case kOTBadNameErr: fprintf(stderr, "Bad Address! Either Address Does Not Exist in Domains Examined, or Bad Syntax!\n"); break; default: fprintf(stderr, "Unknown Error!\n"); break; } gTestResult = kOTNoError; gCallCompleted = false; } void DoSysInfo(char* name) { CleanMySysInfo(); OSStatus err = gSvc->SysInfo(name, &gMySysInfo); if ( err != kOTNoError ) gTestResult = err; else { while ( !gCallCompleted ) ; } switch ( gTestResult) { case kOTNoError: fprintf(stderr, "CPU Type %s\n", gMySysInfo.cpuType); fprintf(stderr, "O/S Type %s\n", gMySysInfo.osType); break; case kENOMEMErr: fprintf(stderr, "Memory Depletion!\n"); break; case kEINVALErr: fprintf(stderr, "Host Address Wrong Size! Shouldn't Happen In This Test!\n"); break; case kOTNoDataErr: fprintf(stderr, "No Data Available! Either Timeout,or Name Exists But Requested Info Doesn't!\n"); break; case kOTBadNameErr: fprintf(stderr, "Bad Name! Either Name Does Not Exist in Domains Examined, or Bad Syntax!\n"); break; default: fprintf(stderr, "Unknown Error!\n"); break; } gCallCompleted = false; gTestResult = kOTNoError; } void DoMailExchange(char* name) { size_t idx; InetMailExchange* mailex; CleanMyMX(); gNumMX = kNumMX; OSStatus err = gSvc->MailExchange( name, &gNumMX, gMyMX); if ( err != kOTNoError ) gTestResult = err; else { while ( !gCallCompleted ) ; } switch ( gTestResult ) { case kOTNoError: for ( idx = 0, mailex = gMyMX; idx < kNumMX; idx++, mailex++) if ( mailex->exchange[0] ) fprintf(stderr, "Exchange = %s, Preference = %d\n", mailex->exchange, mailex->preference); break; case kENOMEMErr: fprintf(stderr, "Memory Depletion!\n"); break; case kEINVALErr: fprintf(stderr, "Host Address Wrong Size! Shouldn't Happen In This Test!\n"); break; case kOTNoDataErr: fprintf(stderr, "No Data Available! Either Timeout,or Name Exists But Requested Info Doesn't!\n"); break; case kOTBadNameErr: fprintf(stderr, "Bad Name! Either Name Does Not Exist in Domains Examined, or Bad Syntax!\n"); break; default: fprintf(stderr, "Unknown Error!\n"); break; } gCallCompleted = false; gTestResult = kOTNoError; } void DoGenericQuery(char* name, UInt16 qclass, UInt16 qtype) { DNSQueryInfo* qptr; int j, i = 0; CleanMyQueryBuf(); OSStatus err = gSvc->Query(name, qclass, qtype, (char *)gQueryBuf, kQueryBufSize, gArgBuf, kArgBufSize, (OTFlags)0); if ( err != kOTNoError ) gTestResult = err; else { while ( !gCallCompleted ) ; } switch ( gTestResult ) { case kOTBufferOverflowErr: fprintf(stderr, "Buffer Overflow! Will print all responses that fit.\n\n"); // Fall through... case kOTNoError: qptr = *((DNSQueryInfo**)gArgBuf); if (qptr != NULL) { fprintf(stderr, "Query Name: %s\n\n", qptr->name); } while ((qptr != NULL) && (i < kArgBufSize)) { fprintf(stderr, "Record %d : %s : ", i, TypeOfRR[qptr->responseType]); fprintf(stderr, "Record Type %s, Record Class %s, TTL %d\n", TypeOfQuery[qptr->qType], TypeOfClass[qptr->qClass], qptr->ttl); switch (qptr->qType) { case kNSType: // Name server, a domain name, compressed case kMDType: // Mail domain (obsolete - use MX), compressed case kMFType: // Mail forwarder (obsolete - use MX), compressed case kCNameType: // Canonical name, compressed case kMBType: // Mailbox domain name (experimental), compressed case kMGType: // Mail group member (experimental), compressed case kMRType: // Mailbox rename (experiemental), compressed case kPtrType: // Ptr (domain name), compressed fprintf(stderr, "%s\n", qptr->resourceData); break; case kWKSType: // Well-Known Services - IP addr, protocol, bitmask { WKSEntry* entry = (WKSEntry*)qptr->resourceData; UInt8* tmpdata = (UInt8 *)(qptr->resourceData) + sizeof(UInt32) + sizeof(UInt8); fprintf(stderr, "IP Address %x, Protocol %s, Bitmask ", *((UInt32 *)(entry->WKSAddr)), TypeOfProtocol[entry->WKSProto]); for (j = 0; j < (qptr->resourceLen - sizeof(UInt8) - sizeof(UInt32)); j++) fprintf(stderr, "%02x", *tmpdata++); fprintf(stderr, "\n"); break; } case kMXType: { UInt16* pref = (UInt16 *)qptr->resourceData; char* server = (char *)(qptr->resourceData) + sizeof (UInt16); fprintf(stderr, "Exchange = %s, Preference = %d\n", server, *pref); break; } case kHInfoType: { char* hstuff = qptr->resourceData; UInt8 slen = (UInt8)(*hstuff++); fprintf(stderr, "CPU Type "); for (j = 0; j< slen; j++) fprintf(stderr, "%c", *hstuff++); slen = (UInt8)(*hstuff++); fprintf(stderr, "\nO/S Type "); for (j = 0; j< slen; j++) fprintf(stderr, "%c", *hstuff++); fprintf(stderr, "\n"); break; } case kAType: { fprintf(stderr, "Address = %d.%d.%d.%d \n", (UInt8)qptr->resourceData[0], (UInt8)qptr->resourceData[1], (UInt8)qptr->resourceData[2], (UInt8)qptr->resourceData[3]); break; } case kSOAType: { char* mname = qptr->resourceData; char* rname = (char *)(qptr->resourceData + strlen(qptr->resourceData) + 1); size_t mnamelen = strlen(mname); size_t rnamelen = strlen(rname); UInt32* myPtr = (UInt32 *)(rname + rnamelen +1); UInt32 serial = *myPtr++; UInt32 refresh = *myPtr++; UInt32 retry = *myPtr++; UInt32 expire = *myPtr++; UInt32 minimum = *myPtr; fprintf(stderr, "MNAME %s, RNAME %s\n", mname, rname); fprintf(stderr, "SERIAL %d, REFRESH %d, RETRY %d, EXPIRE %d, MINIMUM %d\n", serial, refresh, retry, expire, minimum); break; } default: for (j = 0; j < qptr->resourceLen; j++) fprintf(stderr, "%02x", (UInt8)(qptr->resourceData[j])); } fprintf(stderr, "\n"); i++; qptr = *(((DNSQueryInfo**)gArgBuf) + i); }; break; case kENOMEMErr: fprintf(stderr, "Memory Depletion!\n"); break; case kEINVALErr: fprintf(stderr, "Host Address Wrong Size! Shouldn't Happen In This Test!\n"); break; case kOTNoDataErr: fprintf(stderr, "No Data Available! Either Timeout,or Name Exists But Requested Info Doesn't!\n"); break; case kOTBadNameErr: fprintf(stderr, "Bad Name! Either Name Does Not Exist in Domains Examined, or Bad Syntax!\n"); break; default: fprintf(stderr, "Unknown Error %d!\n", gTestResult); break; } gCallCompleted = false; gTestResult = kOTNoError; } pascal void EventHandler(void*, OTEventCode, OTResult result, void*) { gTestResult = result; gCallCompleted = true; return; } int main() { int testtype; int retval = 1; char mystr[kMaxHostNameLen]; char datastr[kMaxHostNameLen]; InetHost addr; OSStatus err; Inits(); fflush(stdout); do { gSvc = OTOpenInternetServices(kDefaultInternetServicesPath, NULL, &err); if ( gSvc == NULL || err != kOTNoError ) { fprintf(stderr,"Could not open Inet Services\n"); return retval; } /* * Now install a notifier for async events * and then go back to async mode. */ err = gSvc->InstallNotifier((OTNotifyProcPtr)&EventHandler, 0); if ( err != kOTNoError ) { fprintf(stderr,"Install notifier failed\n"); return retval; } err = gSvc->SetAsynchronous(); if ( err != kOTNoError ) { fprintf(stderr,"Could not set asynchronous mode on svc\n"); return retval; } do { fprintf(stderr, "Select a DNR operation. \n Enter '1' for StringToAddress, \n '2' for AddressToName, \n '3' for SysInfo, \n '4' for MailExchange, \n '5' for Generic Query, \n or 'q' to quit. \n"); if ( gets(mystr) != 0 ) { if ( strcmp(mystr, "1") == 0 ) testtype = kStrToAddrTest; else if ( strcmp(mystr, "2") == 0 ) testtype = kAddrToNameTest; else if ( strcmp(mystr, "3") == 0 ) testtype = kSysInfoTest; else if ( strcmp(mystr, "4") == 0 ) testtype = kMXTest; else if ( strcmp(mystr, "5") == 0 ) testtype = kQueryTest; else if ( strcmp(mystr, "q") == 0 ) break; else { fprintf(stderr, "Invalid character entered. Please try again.\n"); continue; } } switch ( testtype ) { case kStrToAddrTest: fprintf(stderr, "StringToAddr Test. Please enter a name to resolve...\n"); if ( gets(mystr) != 0 ) DoStrToAddr(mystr); else fprintf(stderr, "Couldn't get name from window!\n"); break; case kAddrToNameTest: fprintf(stderr, "AddressToName Test. Please enter an address to resolve...\n"); if ( gets(mystr) != 0 ) { OTInetStringToHost(mystr, &addr); DoAddrToName(addr); } break; case kSysInfoTest: fprintf(stderr, "SysInfo Test. Please enter a name to resolve...\n"); if ( gets(mystr) != 0 ) DoSysInfo(mystr); else fprintf(stderr, "Couldn't get name from window!\n"); break; case kMXTest: fprintf(stderr, "Mail Exchange Test. Please enter a name to resolve...\n"); if ( gets(mystr) != 0 ) DoMailExchange(mystr); else fprintf(stderr, "Couldn't get name from window!\n"); break; case kQueryTest: { UInt16 queryClass; UInt16 queryType; fprintf(stderr, "Generic Query Test. Please enter a name to resolve...\n"); if ( gets(mystr) == 0 ) { fprintf(stderr, "Couldn't get name from window!\n"); break; } fprintf(stderr, "Please enter the query class (1 for INET; 255 or '*' For All Classes)...\n"); if ( gets(datastr) == 0 ) { fprintf(stderr, "Couldn't get class from window!\n"); break; } if (*datastr == '*') queryClass = kWIldCardType; else queryClass = (UInt16)(atoi(datastr)); fprintf(stderr, "Please enter the query type (1 through 254; 255 or '*' For All Types)...\n"); if ( gets(datastr) == 0 ) { fprintf(stderr, "Couldn't get type from window!\n"); break; } if (*datastr == '*') queryType = kWIldCardType; else queryType = (UInt16)(atoi(datastr)); DoGenericQuery(mystr, queryClass, queryType); break; } default: break; } } while (true); } while ( false ); fprintf(stderr, "Tests Completed.\n"); if ( gSvc != NULL ) gSvc->Close(); return retval; }